﻿namespace MaciejGrabek.WebAPITools
{
    using System;
    using System.Text;
    using System.Net;
    using System.IO;

    public class ServiceCaller
    {
        public string ServiceUrl { get; private set; }

        public ServiceCaller(string serviceUrl)
        {
            ServiceUrl = serviceUrl.TrimEnd(new char[] { '/' });
        }

        public void Get<TResult>(string callActionUrl, Action<TResult> onSuccess, Action<Exception> onError)
        {
            string url = string.Format("{0}/{1}", ServiceUrl, callActionUrl);
            WebClient webClient = new WebClient();

            webClient.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    onError(e.Error);
                    return;
                }

                TResult results =
                    JsonSerializationHelper.Deserialize<TResult>(
                        e.Result);
                onSuccess(results);
            };

            webClient.DownloadStringAsync(new Uri(url));
        }

        private void GetPostResponse<TResult, TBody>(string callActionUrl, TBody body, Action<TResult> onSuccess)
        {
            string url = string.Format("{0}/{1}", ServiceUrl, callActionUrl);
            WebRequest request = WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/json";

            request.BeginGetRequestStream(
                new AsyncCallback((asynchronousResult) =>
                {
                    Stream postStream = request.EndGetRequestStream(asynchronousResult);
                    string jsonBodyString = JsonSerializationHelper.Serialize<TBody>(body);
                    byte[] byteArray = Encoding.UTF8.GetBytes(jsonBodyString);
                    postStream.Write(byteArray, 0, byteArray.Length);
                    postStream.Close();

                    request.BeginGetResponse(
                        new AsyncCallback(
                            ar =>
                                {
                                    var req = (HttpWebRequest)ar.AsyncState;
                                    var resp = (HttpWebResponse)req.EndGetResponse(ar); 
                                    StreamReader streamReader = new StreamReader(resp.GetResponseStream());
                                    string resultString = streamReader.ReadToEnd();
                                    TResult result = JsonSerializationHelper.Deserialize<TResult>(resultString);
                                    onSuccess(result);
                                }), request);
                }), request);
        }
    }
}
